#!/usr/bin/env python
# -*- coding: utf-8 -*-
import datetime
import json
import urllib2
import psutil

SYS_PROCS_ADDR = 'http://172.32.100.232:9000/sysproc/inlist'
sysProcs = []

def _getProcInfo(pid, sconns):
    '''
    :function: 获取指定pid的进程信息(不包括系统进程)
    :param pid: 目标进程pid
    :return: 进程信息字典
    '''
    try:
        p = psutil.Process(pid)

        ## 系列进程cmdline值为空列表, 跳过
        if p.cmdline() == []:
            return None
        ## 遇到手动标记的系统进程, 也跳过
        for sysProc in sysProcs:
            if (' ').join(p.cmdline()).find(sysProc) > -1:
                return None

        proc = {
            'key': p.name(),
            'pid': pid,
            'user': p.username(),
            'port': None,
            'ps_str': ' '.join(p.cmdline()),
            'start_date': p.create_time()
            ## 算了, path值无法准确得到
            ## 'path':         p.exe(), 
            ## http接口时, 这个值无法正常返回, 还是直接返回数值类型吧
            ## 'start_date':   datetime.datetime.fromtimestamp(p.create_time())
        }
        ## 使用enumerate()方法可以在for..in..的同时得到数组下标
        for sconnIdx, sconn in enumerate(sconns):
            if not sconn.pid == pid:
                continue
            else:
                proc['port'] = sconn.laddr.port
                break
        ## 已经取到端口的连接对象, 移出列表, 之后的循环可以更快
        try:
            sconns.pop(sconnIdx)
        except Exception, e:
            pass

        return proc
    except psutil.NoSuchProcess, pid:
        print "no process found with pid=%s" % (pid) 
        return None 

def detect():
    procs = []
    ## 获取标记系统进程列表
    try:
        global sysProcs
        sysProcs = json.loads(urllib2.urlopen(SYS_PROCS_ADDR).read())
    except Exception, e:
        return procs

    ## 得到当前系统的全部进程pid, 全部网络连接, 都是list类型
    pids = psutil.pids()
    sconns = psutil.net_connections()
    ## pid大于1000的进程(一般只有系统进程才小于1000)
    ## for pid in pids:
    ##     if pid >= 1000:
    ##         break
    ## pids = pids[pids.index(pid):]

    for pid in pids:
        proc = _getProcInfo(pid, sconns)
        if not proc == None:
            procs.append(proc)

    print(procs)
    return procs

if __name__ == '__main__':
    detect()
